using System;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using EntityKit.Runtime;
using Excel;
using System.Data;
using System.Threading.Tasks;
using System.Linq;

namespace EntityKit.Editor
{
    public class LocalizationWindow : EditorWindow
    {
        #region Fields and Properties

        private string mExcelFilePath = "";
        
        // 用于存储解析后的数据，以便在主线程中创建资源
        private readonly List<LocalizationEntry> mParsedEntries = new List<LocalizationEntry>();
        
        // 用于存储重复键信息
        private readonly List<DuplicateEntryGroup> mDuplicateEntryGroups = new List<DuplicateEntryGroup>();

        private GUIStyle mHeaderStyle;
        private GUIStyle mBoxStyle;
        private GUIStyle mFilePathStyle;

        // 进度提示相关字段
        private bool mIsProcessing = false;
        private string mProcessingMessage = "";
        private float mProgress = 0f;
        
        private readonly List<Language> mCurrentLanguages = new List<Language>();
        
        // 导入结果信息
        private string mImportResultMessage = "";
        private MessageType mImportResultType = MessageType.None;
        
        // 重复键信息滚动位置
        private Vector2 mScrollPosition = Vector2.zero;

        #endregion

        #region Menu Item
        
        public static void ShowWindow()
        {
            LocalizationWindow window = GetWindow<LocalizationWindow>("本地化窗口");
            window.minSize = new Vector2(500, 400);
        }

        #endregion

        #region Unity Lifecycle

        private void OnEnable()
        {
            InitializeStyles();
        }

        private void OnGUI()
        {
            InitializeStyles();

            EditorGUILayout.Space(10);
            EditorGUILayout.LabelField("本地化数据导入", mHeaderStyle);
            EditorGUILayout.HelpBox("拖拽Excel文件和本地化配置资源以导入本地化数据。", MessageType.Info);

            // Excel文件拖拽区域
            DrawExcelFileDragArea();

            EditorGUILayout.Space(10);

            // 操作按钮
            EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(mExcelFilePath) || mIsProcessing);
            if (GUILayout.Button("导入数据", GUILayout.Height(30)))
            {
                ImportDataAsync();
            }
            EditorGUI.EndDisabledGroup();

            // 显示进度提示
            if (mIsProcessing)
            {
                EditorGUI.ProgressBar(EditorGUILayout.GetControlRect(), mProgress, mProcessingMessage);
            }
            
            // 显示导入结果信息
            if (!string.IsNullOrEmpty(mImportResultMessage))
            {
                EditorGUILayout.HelpBox(mImportResultMessage, mImportResultType);
            }
            
            // 显示重复键信息
            if (mDuplicateEntryGroups.Count > 0)
            {
                DrawDuplicateEntriesInfo();
            }
        }

        #endregion

        #region Initialization

        private void InitializeStyles()
        {
            mHeaderStyle ??= new GUIStyle(EditorStyles.largeLabel)
            {
                fontStyle = FontStyle.Bold,
                fontSize = 16
            };

            mBoxStyle ??= new GUIStyle(EditorStyles.helpBox);

            mFilePathStyle ??= new GUIStyle(EditorStyles.label)
            {
                alignment = TextAnchor.MiddleLeft
            };
        }

        #endregion

        #region Data Import

        private async void ImportDataAsync()
        {
            mIsProcessing = true;
            mProgress = 0f;
            mProcessingMessage = "正在读取Excel文件...";
            mDuplicateEntryGroups.Clear();
            mImportResultMessage = "";
            Repaint();

            try
            {
                await Task.Run(ImportDataWithDuplicateCheck);
            }
            catch (Exception ex)
            {
                Debug.LogError($"读取Excel文件时出错: {ex.Message}");
                mImportResultMessage = $"读取Excel文件时出错: {ex.Message}";
                mImportResultType = MessageType.Error;
                ResetProcessingState();
            }
        }

        private void ImportDataWithDuplicateCheck()
        {
            if (!mIsProcessing)
                return;

            UpdateProcessingMessage("正在解析Excel数据...", 0.1f);

            try
            {
                if (string.IsNullOrEmpty(mExcelFilePath))
                {
                    mIsProcessing = false;
                    return;
                }

                // 每次都重新读取文件，不使用缓存数据
                DataTableCollection dataTables = null;
                using (var stream = File.Open(mExcelFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (var reader = ExcelReaderFactory.CreateOpenXmlReader(stream))
                    {
                        var dataSet = reader.AsDataSet();
                        dataTables = dataSet.Tables;
                    }
                }

                UpdateProcessingMessage("正在识别语言...", 0.3f);
                SetCurrentLanguagesAsync(dataTables);

                UpdateProcessingMessage("正在检查重复键...", 0.5f);
                if (!FindDuplicateKeys(dataTables))
                {
                    // 如果发现重复键，直接返回
                    EditorApplication.delayCall += () => {
                        Repaint();
                        ResetProcessingState();
                    };
                    return;
                }

                UpdateProcessingMessage("正在处理数据...", 0.7f);
                ReadDataAsync(dataTables);
            }
            catch (Exception ex)
            {
                Debug.LogError($"解析Excel文件时出错: {ex.Message}");
                EditorApplication.delayCall += () => {
                    mImportResultMessage = $"解析Excel文件时出错: {ex.Message}";
                    mImportResultType = MessageType.Error;
                    ResetProcessingState();
                    Repaint();
                };
            }
        }
        
        private void SetCurrentLanguagesAsync(DataTableCollection dataTables)
        {
            try
            {
                mCurrentLanguages.Clear();
                if (dataTables != null && dataTables.Count > 0)
                {
                    var dataSetTable = dataTables[0];
                    if (dataSetTable.Rows.Count > 2) // 确保至少有3行数据（行索引从0开始）
                    {
                        for (int col = 0; col < dataSetTable.Columns.Count; col++)
                        {
                            var cellValue = dataSetTable.Rows[2][col].ToString();
                            if (Enum.TryParse(cellValue, out Language language))
                            {
                                mCurrentLanguages.Add(language);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"识别语言时出错: {ex.Message}");
            }
        }

        private bool FindDuplicateKeys(DataTableCollection dataTables)
        {
            try
            {
                if (dataTables == null)
                {
                    Debug.LogError("数据表为空，请检查Excel文件");
                    EditorApplication.delayCall += () => {
                        mImportResultMessage = "数据表为空，请检查Excel文件";
                        mImportResultType = MessageType.Error;
                        ResetProcessingState();
                        Repaint();
                    };
                    return false;
                }

                UpdateProcessingMessage("正在检查重复键...", 0.6f);

                // 清空之前的重复键数据
                mDuplicateEntryGroups.Clear();

                // 遍历每个工作表单独检查重复键
                foreach (DataTable table in dataTables)
                {
                    // 用于检查当前工作表内的重复键，只存储键名和其位置信息
                    var entryKeys = new Dictionary<string, List<EntryPositionInfo>>();
                    
                    // 遍历当前工作表中的所有行，从第4行开始（索引为3）
                    for (int row = 3; row < table.Rows.Count; row++)
                    {
                        // 检查是否为空行
                        if (IsRowEmpty(table, row))
                            continue;

                        string key = table.Rows[row][0].ToString();
                        // 确保键不为空
                        if (!string.IsNullOrEmpty(key))
                        {
                            // 记录位置信息
                            var currentPosition = new EntryPositionInfo
                            {
                                SheetName = table.TableName,
                                RowIndex = row + 1, // Excel行号从1开始
                                Key = key
                            };
                            
                            // 按键分组存储位置信息（仅在当前工作表内）
                            if (!entryKeys.ContainsKey(key))
                            {
                                entryKeys[key] = new List<EntryPositionInfo>();
                            }
                            entryKeys[key].Add(currentPosition);
                        }
                    }
                    
                    // 查找当前工作表内有重复的位置信息
                    foreach (var kvp in entryKeys)
                    {
                        if (kvp.Value.Count > 1) // 只处理重复的键
                        {
                            mDuplicateEntryGroups.Add(new DuplicateEntryGroup
                            {
                                Key = kvp.Key,
                                Positions = kvp.Value
                            });
                        }
                    }
                }

                UpdateProcessingMessage("检查完成", 0.7f);
                
                // 如果发现重复键，返回false
                if (mDuplicateEntryGroups.Count > 0)
                {
                    EditorApplication.delayCall += () => {
                        mImportResultMessage = $"发现 {mDuplicateEntryGroups.Count} 个重复键，请查看下方详细信息。";
                        mImportResultType = MessageType.Warning;
                        Repaint();
                    };
                    return false;
                }
                
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError($"检查重复键时出错: {ex.Message}");
                EditorApplication.delayCall += () => {
                    mImportResultMessage = $"检查重复键时出错: {ex.Message}";
                    mImportResultType = MessageType.Error;
                    ResetProcessingState();
                    Repaint();
                };
                return false;
            }
        }

        private void ReadDataAsync(DataTableCollection dataTables)
        {
            try
            {
                if (dataTables == null)
                {
                    Debug.LogError("数据表为空，请检查Excel文件");
                    EditorApplication.delayCall += () => {
                        mImportResultMessage = "数据表为空，请检查Excel文件";
                        mImportResultType = MessageType.Error;
                        ResetProcessingState();
                        Repaint();
                    };
                    return;
                }

                UpdateProcessingMessage("正在解析本地化数据...", 0.8f);

                // 清空之前的数据
                mParsedEntries.Clear();

                int languageCount = mCurrentLanguages.Count;
                int processedLanguages = 0;

                for (int i = 0; i < languageCount; i++)
                {
                    var language = mCurrentLanguages[i];
                    processedLanguages++;
                    UpdateProcessingMessage($"正在处理语言: {language} ({processedLanguages}/{languageCount})", 0.8f + 0.1f * processedLanguages / languageCount);

                    var localizationTypes = Enum.GetValues(typeof(LocalizationType));
                    for (int j = 0; j < localizationTypes.Length; j++)
                    {
                        var type = (LocalizationType)localizationTypes.GetValue(j);

                        // 遍历所有工作表查找匹配的类型
                        foreach (DataTable table in dataTables)
                        {
                            if (type.ToString() == table.TableName)
                            {
                                // 获取当前语言列的索引
                                int languageColumnIndex = -1;
                                for (int c = 0; c < table.Columns.Count; c++)
                                {
                                    // 检查是否为空列
                                    if (IsColumnEmpty(table, c))
                                        continue;

                                    if (table.Rows[2][c].ToString() == language.ToString())
                                    {
                                        languageColumnIndex = c;
                                        break;
                                    }
                                }

                                // 如果找到了对应的语言列，则读取数据
                                if (languageColumnIndex != -1)
                                {
                                    // 从第4行开始读取数据（行索引从0开始，第4行是索引3）
                                    for (int row = 3; row < table.Rows.Count; row++)
                                    {
                                        // 检查是否为空行
                                        if (IsRowEmpty(table, row))
                                            continue;

                                        string key = table.Rows[row][0].ToString();
                                        // 确保键不为空
                                        if (!string.IsNullOrEmpty(key))
                                        {
                                            string value = table.Rows[row][languageColumnIndex].ToString();
                                            // 添加到解析列表中
                                            mParsedEntries.Add(new LocalizationEntry(language, type, key, value));
                                        }
                                    }
                                }
                                break;
                            }
                        }
                    }
                }

                UpdateProcessingMessage("正在创建资源文件...", 0.95f);

                // 在主线程中创建资源文件
                EditorApplication.delayCall += CreateAssetOnMainThread;
            }
            catch (Exception ex)
            {
                Debug.LogError($"处理数据时出错: {ex.Message}");
                EditorApplication.delayCall += () => {
                    mImportResultMessage = $"处理数据时出错: {ex.Message}";
                    mImportResultType = MessageType.Error;
                    ResetProcessingState();
                    Repaint();
                };
            }
        }

        private void CreateAssetOnMainThread()
        {
            try
            {
                // 在主线程中创建LocalizationConfig实例
                LocalizationConfig config = ScriptableObject.CreateInstance<LocalizationConfig>();
                
                // 添加所有解析的数据条目
                foreach (var entry in mParsedEntries)
                {
                    config.AddEntry(entry.Language, entry.Type, entry.Key, entry.Value);
                }

                // 获取Excel文件的目录和文件名（不含扩展名），并转换为相对于项目文件夹的路径
                string projectPath = Application.dataPath.Replace("/Assets", "");
                string excelDirectory = Path.GetDirectoryName(mExcelFilePath);
                string relativePath = excelDirectory.Substring(projectPath.Length + 1); // 获取相对于项目文件夹的路径
                string excelFileNameWithoutExtension = Path.GetFileNameWithoutExtension(mExcelFilePath);
                string assetPath = Path.Combine(relativePath, excelFileNameWithoutExtension + ".asset");

                AssetDatabase.CreateAsset(config, assetPath);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();

                // 不再显示弹框，直接在界面显示结果
                mImportResultMessage = $"本地化配置文件已创建: {assetPath}";
                mImportResultType = MessageType.Info;
                Debug.Log($"本地化配置文件已创建: {assetPath}");
            }
            catch (Exception ex)
            {
                Debug.LogError($"创建资源文件时出错: {ex.Message}");
                mImportResultMessage = $"创建资源文件时出错: {ex.Message}";
                mImportResultType = MessageType.Error;
            }
            finally
            {
                ResetProcessingState();
                mParsedEntries.Clear();
                Repaint();
            }
        }

        #endregion

        #region UI Drawing

        private void DrawExcelFileDragArea()
        {
            EditorGUILayout.LabelField("Excel文件", EditorStyles.boldLabel);
            EditorGUILayout.BeginVertical(mBoxStyle);

            Rect dropArea = GUILayoutUtility.GetRect(0.0f, 30.0f, GUILayout.ExpandWidth(true));
            GUI.Box(dropArea, !string.IsNullOrEmpty(mExcelFilePath) ? Path.GetFileName(mExcelFilePath) : "请拖拽Excel文件到此处", mFilePathStyle);

            // 处理拖拽事件
            EventType eventType = Event.current.type;
            if (eventType == EventType.DragUpdated || eventType == EventType.DragPerform)
            {
                if (dropArea.Contains(Event.current.mousePosition))
                {
                    DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                    if (eventType == EventType.DragPerform)
                    {
                        DragAndDrop.AcceptDrag();

                        foreach (string draggedPath in DragAndDrop.paths)
                        {
                            string fullPath = Path.GetFullPath(draggedPath);

                            // 检查是否是Excel文件 (通过文件扩展名)
                            string extension = Path.GetExtension(fullPath)?.ToLower();
                            if (extension == ".xlsx" || extension == ".xls")
                            {
                                mExcelFilePath = fullPath;
                                mDuplicateEntryGroups.Clear(); // 清除之前的重复信息
                                mImportResultMessage = ""; // 清除导入结果信息
                                break;
                            }
                        }

                        Event.current.Use();
                    }
                }
            }

            // 显示当前选择的文件路径
            if (!string.IsNullOrEmpty(mExcelFilePath))
            {
                EditorGUILayout.LabelField("文件路径:", mExcelFilePath);
            }

            EditorGUILayout.EndVertical();
        }
        
        private void DrawDuplicateEntriesInfo()
        {
            EditorGUILayout.BeginVertical(mBoxStyle);
            if (mDuplicateEntryGroups.Count > 0)
            {
                EditorGUILayout.LabelField("发现重复键", EditorStyles.boldLabel);
                EditorGUILayout.HelpBox($"发现 {mDuplicateEntryGroups.Count} 个重复键。", MessageType.Warning);
                
                // 添加滚动视图，使重复键信息可以滑动查看
                mScrollPosition = EditorGUILayout.BeginScrollView(mScrollPosition, GUILayout.Height(200));
                
                // 显示所有重复项组的详细信息
                for (int i = 0; i < mDuplicateEntryGroups.Count; i++)
                {
                    var group = mDuplicateEntryGroups[i];
                    EditorGUILayout.LabelField($"重复键: {group.Key}");
                    EditorGUILayout.LabelField($"  工作表: {group.Positions[0].SheetName}");
                    
                    // 显示所有重复位置
                    foreach (var position in group.Positions)
                    {
                        EditorGUILayout.LabelField($"    第 {position.RowIndex} 行");
                    }
                    
                    EditorGUILayout.Space();
                }
                
                EditorGUILayout.EndScrollView();
            }
            else
            {
                EditorGUILayout.LabelField("重复键检查", EditorStyles.boldLabel);
                EditorGUILayout.HelpBox("未发现重复键。", MessageType.Info);
            }
            
            EditorGUILayout.EndVertical();
        }

        #endregion

        #region Helper Methods

        private void UpdateProcessingMessage(string message, float progress = -1f)
        {
            EditorApplication.delayCall += () => {
                mProcessingMessage = message;
                if (progress >= 0)
                    mProgress = progress;
                Repaint();
            };
        }

        private void ResetProcessingState()
        {
            mIsProcessing = false;
            mProgress = 0f;
            mProcessingMessage = "";
        }

        /// <summary>
        /// 检查指定行是否为空行
        /// </summary>
        /// <param name="table">数据表</param>
        /// <param name="rowIndex">行索引</param>
        /// <returns>是否为空行</returns>
        private bool IsRowEmpty(DataTable table, int rowIndex)
        {
            // 检查行索引是否有效
            if (rowIndex < 0 || rowIndex >= table.Rows.Count)
                return true;

            var row = table.Rows[rowIndex];
            
            // 检查该行的所有列是否都为空
            for (int col = 0; col < table.Columns.Count; col++)
            {
                var cellValue = row[col];
                // 如果单元格不为空且不是DBNull且不为空字符串，则不是空行
                if (cellValue != null && !(cellValue is DBNull) && !string.IsNullOrEmpty(cellValue.ToString().Trim()))
                {
                    return false;
                }
            }
            
            return true; // 所有单元格都为空，是空行
        }

        /// <summary>
        /// 检查指定列是否为空列
        /// </summary>
        /// <param name="table">数据表</param>
        /// <param name="columnIndex">列索引</param>
        /// <returns>是否为空列</returns>
        private bool IsColumnEmpty(DataTable table, int columnIndex)
        {
            // 检查列索引是否有效
            if (columnIndex < 0 || columnIndex >= table.Columns.Count)
                return true;

            // 检查该列的所有行是否都为空
            for (int row = 0; row < table.Rows.Count; row++)
            {
                var cellValue = table.Rows[row][columnIndex];
                // 如果单元格不为空且不是DBNull且不为空字符串，则不是空列
                if (cellValue != null && !(cellValue is DBNull) && !string.IsNullOrEmpty(cellValue.ToString().Trim()))
                {
                    return false;
                }
            }
            
            return true; // 所有单元格都为空，是空列
        }

        #endregion
    }
    
    // 用于存储重复键组信息的结构
    public struct DuplicateEntryGroup
    {
        public string Key;
        public List<EntryPositionInfo> Positions;
    }
    
    // 用于存储条目位置信息的结构
    public struct EntryPositionInfo
    {
        public string SheetName;
        public int RowIndex;
        public string Key;
    }
}